/* * $Id$ * * Copyright 2006, The jCoderZ.org Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the jCoderZ.org Project nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.jcoderz.phoenix.report; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Execute; import org.apache.tools.ant.taskdefs.LogStreamHandler; import org.apache.tools.ant.taskdefs.MatchingTask; import org.apache.tools.ant.types.Commandline; import org.apache.tools.ant.types.CommandlineJava; import org.apache.tools.ant.types.Environment; import org.apache.tools.ant.types.Path; /** * Report Normalizer Ant Task. * * This Task takes none, one or more input reports such as Checkstyle or PMD * and generates a normalized report file (XML) for any Java source under * <code>srcdir</code>. * This version of the class JcoderzReportAntTask just creates the combined XML * report. No further processing into a HTML report is done at this time. * * @author Michael Griffel (Michael.Griffel@jcoderz.org) * @author Michael Rumpf (Michael.Rumpf@jcoderz.org) */ public final class ReportNormalizerAntTask extends MatchingTask { /** the current working directory when forking JVM */ private File mWorkingDir = null; /** Output directory for XML/HTML report */ private File mOut = new File("."); /** The Filter Filename */ private File mFilter = null; /** The project's name */ private String mName = "Not defined"; /** Flag: exit build process if an error occurred */ private boolean mFailOnError = false; /** The level of the report */ private ReportLevel mLevel = ReportLevel.PROD; /** List of input report of type JcoderzReportAntTask.Report */ private final List mReportFiles = new ArrayList(); /** The Java Commandline */ private final CommandlineJava mCommandline = new CommandlineJava(); /** * List of source directories of type JcoderzReportAntTask.SourceDirectory. */ private final List mSourceDirectories = new ArrayList(); /** Debug output flag */ private boolean mDebug = false; /** * Sets the output directory to given <code>dir</code>. * This directory is used to store the XML/HTML report file(s). * @param dir The output directory to set. */ public void setOut (File dir) { mOut = dir; } /** * Sets the filter file to <code>f</code>. * This file is used to filter to raw jcoderz XML report. * * @param f The filter file. */ public void setFilter (File f) { mFilter = f; } /** * Sets the projectName to given <code>projectName</code>. * @param projectName The projectName to set. */ public void setName (String projectName) { mName = projectName; } /** * Sets the level to given <code>level</code>. * @param level The level to set. */ public void setLevel (String level) { mLevel = ReportLevel.fromString(level); } /** * The directory to invoke the VM in. Ignored if no JVM is forked. * @param dir the directory to invoke the JVM from. */ public void setDir (File dir) { mWorkingDir = dir; } /** * Set whether we should fail on an error. * * @param b Whether we should fail on an error. */ public void setFailonerror (boolean b) { mFailOnError = b; } public void setDebug (boolean b) { mDebug = b; } /** * Adds a classpath to the task. * @return The newly created classpath. */ public Path createClasspath () { return mCommandline.createClasspath(getProject()).createPath(); } /** * Adds a bootclasspath to the task. * @return The newly created bootclasspath. */ public Path createBootclasspath () { return mCommandline.createBootclasspath(getProject()).createPath(); } /** * Adds a system property. * * @param sysp system property */ public void addSysproperty (Environment.Variable sysp) { mCommandline.addSysproperty(sysp); } /** * Adds a JVM argument. * * @return The newly created Command line argument. */ public Commandline.Argument createJvmarg () { return mCommandline.createVmArgument(); } /** * Adds a Report file such as PMD report or checkstyle report. * @return The newly create report file. */ public Report createReport () { final Report ret = new Report(); mReportFiles.add(ret); return ret; } /** * Adds a source folder file such as PMD report or checkstyle report. * @return The newly create report file. */ public SourceDirectory createSrcDir () { final SourceDirectory ret = new SourceDirectory(); mSourceDirectories.add(ret); return ret; } /** * Execute this task. * * @throws BuildException An building exception occurred. */ public void execute () throws BuildException { checkParameters(); try { int exitValue; exitValue = executeAsForked(); if (exitValue != 0) { final String msg = "ReportNormalizer returned with exit code '" + exitValue + "'"; log(msg, Project.MSG_WARN); throw new BuildException(msg, getLocation()); } } catch (BuildException e) { if (mFailOnError) { throw e; } else { log(e.getMessage(), Project.MSG_ERR); } } } /** * Create a Java command line for executing the ReportNormalizer. * * @param suite The suite to run * @return The Java command line. */ private CommandlineJava createCommandline () { final CommandlineJava cmd; try { cmd = (CommandlineJava) mCommandline.clone(); } catch (CloneNotSupportedException unexpected) { throw new RuntimeException( "Ups, CommandLineJava doesn't support the method clone()", unexpected); } cmd.setClassname(ReportNormalizer.class.getName()); // WOW cmd.createVmArgument().setValue("-Xmx1500m"); cmd.createArgument().setValue("-out"); cmd.createArgument().setFile(mOut); cmd.createArgument().setValue("-projectName"); cmd.createArgument().setValue(mName); cmd.createArgument().setValue("-level"); cmd.createArgument().setValue(mLevel.toString()); cmd.createArgument().setValue("-loglevel"); if (mDebug) { cmd.createArgument().setValue("ALL"); } else { cmd.createArgument().setValue("INFO"); } if (mFilter != null) { cmd.createArgument().setValue("-filter"); cmd.createArgument().setFile(mFilter); } for (final Iterator iterator = mSourceDirectories.iterator(); iterator.hasNext();) { final SourceDirectory sourceDir = (SourceDirectory) iterator.next(); cmd.createArgument().setValue("-srcDir"); cmd.createArgument().setPath( new Path(getProject(), sourceDir.getDir())); } for (final Iterator iterator = mReportFiles.iterator(); iterator.hasNext();) { final Report reportFile = (Report) iterator.next(); if (reportFile.testIfCondition()) { cmd.createArgument().setValue("-" + reportFile.getFormat()); cmd.createArgument().setFile(reportFile.getFile()); } } return cmd; } private int executeAsForked () throws BuildException { final Execute execute = new Execute(new LogStreamHandler( this, Project.MSG_INFO, Project.MSG_WARN)); final CommandlineJava cmd = createCommandline(); execute.setCommandline(cmd.getCommandline()); if (mWorkingDir != null) { log("Setting working directory to : " + mWorkingDir, Project.MSG_VERBOSE); execute.setWorkingDirectory(mWorkingDir); execute.setAntRun(getProject()); } final Path classpath = mCommandline.getClasspath(); if (classpath != null) { log("Using CLASSPATH " + classpath, Project.MSG_VERBOSE); } log("Executing: [fork] " + cmd.toString(), Project.MSG_VERBOSE); try { return execute.execute(); } catch (IOException e) { throw new BuildException("Process fork failed.", e, getLocation()); } } private void checkParameters () { if (mSourceDirectories.size() == 0) { throw new BuildException( "at least one srcdir element must be specified!", getLocation()); } } /** This class represents an input report with a format and filename. */ public final class Report { private ReportFormat mReportFormat; private File mReportFilename; private String mIfCondition = ""; /** * Returns the reportFilename. * @return the reportFilename. */ public File getFile () { return mReportFilename; } /** * Sets the reportFilename to given <code>reportFilename</code>. * @param reportFilename The reportFilename to set. */ public void setFile (File reportFilename) { mReportFilename = reportFilename; } /** * Returns the reportFormat. * @return the reportFormat. */ public ReportFormat getFormat () { return mReportFormat; } /** * Sets the reportFormat to given <code>reportFormat</code>. * @param reportFormat The reportFormat to set. */ public void setFormat (String reportFormat) { mReportFormat = ReportFormat.fromString(reportFormat); } /** * Only use report file if the property is set to <code>true</code>. * @param property the property name to check. */ public void setif (String property) { mIfCondition = (property == null) ? "" : property; } /** * Tests whether or not the "if" condition is satisfied. * * @return whether or not the "if" condition is satisfied. If no * condition (or an empty condition) has been set, * <code>true</code> is returned. */ private boolean testIfCondition () { final boolean result; if ("".equals(mIfCondition)) { result = true; } else { final String test = getProject().replaceProperties(mIfCondition); result = getProject().getProperty(test) != null; } return result; } } public static final class SourceDirectory { private String mSourceDir; /** * Returns the sourceDir. * @return the sourceDir. */ public String getDir () { return mSourceDir; } /** * Sets the sourceDir to given <code>sourceDir</code>. * @param sourceDir The sourceDir to set. */ public void setDir (String sourceDir) { mSourceDir = sourceDir; } } }